# -*- coding:utf-8 -*-
# 北梦测教育
# 课程咨询加微信：xiaobeiceshi
import requests
import logging
from utils.slow_api_write_csv import ApiLogger
import threading
import allure
from utils.crypto_utils import crypto_decrypt
from config.config import priKey_str


class HttpRequester(object):
    def __init__(self, timeout=3):
        self.__timeout = timeout
        self.__api_logger = ApiLogger()

    def __log_slow_api_async(self, res, request_data, response):
        """
        异步写入慢接口的函数
        :param res: 返回的结果的原始内容
        :param request_data:请求的参数
        :param response: 返回结果的组装内容
        :return:
        """

        def log():
            self.__api_logger.log_request(res.url, request_data["method"], request_data.get("params"),
                                          request_data.get("data"),
                                          request_data.get("json"), response.get("response_time"))

        threading.Thread(target=log).start()

    @allure.step("2.发送HTTP请求")
    def send_request(self, **request_data):
        """
        提供给外部调用的发起请求的方法，本质发起请求是通过私有方法来实现的
        :param request_data: 请求需要的字典数据
        :return: 请求之后的response
        """
        return self.__send_request(**request_data)

    def __send_request(self, **request_data):
        """
        发起请求的详细逻辑
        :param request_data:请求需要的字典数据
        :return: 请求之后的response
        """

        # 必填项参数
        requited_field = ["method", "url"]
        if not all(field in request_data for field in requited_field):
            raise ValueError(f'http请求缺少必传的参数：{requited_field}')

        # 把默认超时时间加入到请求的参数字典里面去
        request_data.setdefault("timeout", self.__timeout)

        try:
            # 发起请求
            # res = requests.request(**request_data)

            with requests.Session() as session:
                res = session.request(**request_data)

        except requests.RequestException as e:
            logging.error(f"HTTP请求失败，异常是：{e}")
            logging.error(f"HTTP请求失败，参数是：{request_data}")
            return {"error": str(e)}
        except Exception as e:
            logging.error(f"发送未知错误：{e}")
            return {"error": str(e)}

        else:
            # 判断返回值是否是json，是json就转json，不是就转文本
            try:

                data = res.json()

                # 获取返回值里面的data，这个可能是加密的数据
                data_data = data.get("data")

                # 如果data是字符串的类型，就判断为加密的方式，然后调用解密的方法
                if isinstance(data_data, str):
                    data = crypto_decrypt(priKey_str, data_data)

            except ValueError:
                data = res.text

            response = {
                "status_code": res.status_code,
                "json_data": data,
                "response_time": res.elapsed.total_seconds() * 1000
            }
            # 写入慢接口
            # self.__api_logger.log_request(res.url, request_data["method"], request_data["params"], request_data["data"],
            #                              request_data["json"], response["response_time"])

            # 调用异步写入慢接口
            self.__log_slow_api_async(res, request_data, response)

            logging.info(f"2.发送HTTP请求, 响应内容为: {response}")
            return response


if __name__ == '__main__':
    hr = HttpRequester()
    hr.send_request(method="get", url2="www.baidu.com")
